﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Entity;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Input;
using System.Xml.Serialization;
using IDT.Dal;
using IDT.Downloader;
using IDT.Entity;
using log4net;
using log4net.Config;
using MenuItem = System.Windows.Controls.MenuItem;
using MessageBox = System.Windows.MessageBox;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;

[assembly: log4net.Config.XmlConfigurator(Watch = true)]
namespace IDT.Wpf.Watcher
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow
    {
        private ImageDownloader imageDownloader;

        private ILog logger = LogManager.GetLogger(typeof(MainWindow));

        public MainWindow()
        {
            InitializeComponent();
        }

        private async void DoWindowLoaded(object sender, RoutedEventArgs e)
        {
            await LoadWebInforXmlConfiguration();
        }

        private async void DoComboBoxWebsiteSelectedIndexChanged(object sender, SelectionChangedEventArgs e)
        {
            WebInfo webInfo = ComboBoxCWebsites.SelectedItem as WebInfo;
            if (webInfo != null)
            {
                await BindComboBoxCategory(webInfo);
            }
        }

        private async Task BindComboBoxCategory(WebInfo webInfo)
        {
            imageDownloader = new ImageDownloader(webInfo);
            CategoryCollection categories = await imageDownloader.GetCategories();

            ComboBoxCategories.ItemsSource = categories;
            ComboBoxCategories.SelectedIndex = 0;
        }

        private async void DoComboboxCategorySelectedIndexChanged(object sender, SelectionChangedEventArgs e)
        {
            Category category = ComboBoxCategories.SelectedItem as Category;
            if (category != null)
            {
                await BindComboBoxAlbums(category);
            }
        }

        private async Task BindComboBoxAlbums(Category category)
        {
            List<Album> albums = category.Albums;
            if (albums.Count == 0)
            {
                albums = await imageDownloader.GetAlbumsForCategory(category);
            }

            if (albums.Count > 0)
            {
                ComboBoxAlbums.ItemsSource = albums;
                ComboBoxAlbums.SelectedIndex = 0;
            }
        }

        private async void DoComboboxAlbumSelectedIndexChanged(object sender, SelectionChangedEventArgs e)
        {
            Album album = ComboBoxAlbums.SelectedItem as Album;
            if (album != null)
            {
                await BindAlbumImages(album);
            }
        }

        private async Task BindAlbumImages(Album album)
        {
            if (album.Photos == null || album.Photos.Count == 0)
            {
                album.Photos = await imageDownloader.GetPhotosForAlbum(album);
            }

            ListBoxImages.ItemsSource = album.Photos;
            ListBoxImages.SelectedIndex = 0;
        }

        private void DoImageMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            ListBoxImages.SelectedIndex = ListBoxImages.SelectedIndex == ListBoxImages.Items.Count - 1
                ? 0
                : ListBoxImages.SelectedIndex + 1;
        }

        private void DoImageMouseWheel(object sender, MouseWheelEventArgs e)
        {
            // Down: -120; Up: 120;
            //this.lblPictureName.Text = mouseEventArgs.Delta.ToString();
            int preIndex = ListBoxImages.SelectedIndex;

            preIndex = e.Delta < 0 ? ++preIndex : --preIndex;
            preIndex = preIndex <= 0 ? 0 : preIndex;

            int nextIndex = preIndex%ListBoxImages.Items.Count;
            ListBoxImages.SelectedIndex = nextIndex;
        }


        private async void ReloadWebInforXmlConfiguration(object sender, RoutedEventArgs e)
        {
            await LoadWebInforXmlConfiguration();
        }

        private async Task LoadWebInforXmlConfiguration()
        {
            WebInfoCollection webInfos = new WebInfoCollection();
            await Task.Run(() =>
            {
                string xmlPath = "WebInfos.xml";
                FileStream fs = new FileStream(xmlPath, FileMode.Open, FileAccess.Read);
                XmlSerializer serializer = new XmlSerializer(typeof (WebInfoCollection));
                var webInfoCollection = serializer.Deserialize(fs) as WebInfoCollection;
                if (webInfoCollection != null)
                {
                    foreach (var webInfo in webInfoCollection)
                    {
                        if (!webInfo.IsSkipped)
                        {
                            webInfos.Add(webInfo);
                        }
                    }
                }

                fs.Close();
            });

            ComboBoxCWebsites.ItemsSource = webInfos;
            ComboBoxCWebsites.SelectedIndex = 0;
        }

        private async void DoMenuOpenFileClicked(object sender, ExecutedRoutedEventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.DefaultExt = "xml";
            dialog.Filter = "XML File|*.xml";
            if (dialog.ShowDialog(this).GetValueOrDefault())
            {
                try
                {
                    XmlSerializer serializer = new XmlSerializer(typeof (CategoryCollection));
                    CategoryCollection categories =
                        await Task.Run(() => serializer.Deserialize(dialog.OpenFile()) as CategoryCollection);
                    await Task.Run(() =>
                    {
                        Parallel.ForEach(categories, category =>
                        {
                            Parallel.ForEach(category.Albums, album =>
                            {
                                album.Category = category;
                                album.AlbumCover.Album = album;

                                Parallel.ForEach(album.Photos, photo =>
                                {
                                    photo.Album = album;
                                });
                            });
                        });
                    });

                    ComboBoxCategories.ItemsSource = categories;
                    ComboBoxCategories.SelectedIndex = 0;
                }
                catch (Exception exception)
                {
                    logger.Error("Open File", exception);
                    // ignored
                }
            }
        }

        private void DownloadImages(object sender, RoutedEventArgs e)
        {
            MenuItem menuItem = sender as MenuItem;
            if (menuItem != null)
            {
                string tag = menuItem.Tag as string;
                DownloadType downloadType = (DownloadType)Enum.Parse(typeof (DownloadType), tag);

                FolderBrowserDialog dialog = new FolderBrowserDialog();
                dialog.ShowNewFolderButton = true;

                if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    DirectoryInfo directory = new DirectoryInfo(dialog.SelectedPath);
                    DownloadImageWindow window = GetDownloadImageWindow(downloadType, directory);
                    window?.Show();
                }
            }
        }

        private DownloadImageWindow GetDownloadImageWindow(DownloadType downloadType, DirectoryInfo directory)
        {
            DownloadImageWindow window = null;
            switch (downloadType)
            {
                case DownloadType.Website:
                    CategoryCollection categories = ComboBoxCategories.ItemsSource as CategoryCollection;
                    window = categories != null ? new DownloadImageWindow(downloadType, directory, categories, imageDownloader) : null;
                    break;
                case DownloadType.Category:
                    Category  category= ComboBoxCategories.SelectedItem as Category;
                    window = category != null ? new DownloadImageWindow(downloadType, directory, category, imageDownloader) : null;
                    break;
                case DownloadType.Album:
                    Album album = ComboBoxAlbums.SelectedItem as Album;
                    window = album != null ? new DownloadImageWindow(downloadType, directory, album, imageDownloader) : null;
                    break;
                case DownloadType.Image:
                    Photo photo = ListBoxImages.SelectedItem as Photo;
                    window = photo != null ? new DownloadImageWindow(downloadType, directory, photo, imageDownloader) : null;
                    break;
            }

            return window;
        }

        private void DoMenuLoadWebsiteSchemaClicked(object sender, RoutedEventArgs e)
        {
            WebInfo webInfo = ComboBoxCWebsites.SelectedItem as WebInfo;
            ImageDownloader imageDownloader = new ImageDownloader(webInfo);
            LoadWebSchemaWindow window = new LoadWebSchemaWindow(imageDownloader);

            window.Show();
        }

        private void DoMenuGenerateDBClicked(object sender, RoutedEventArgs e)
        {
            DatabaseManagementWindow window = new DatabaseManagementWindow();
            window.Show();
        }

        [XmlRoot("Root")]
        public class WebInfoCollection : Collection<WebInfo>
        {
            
        }
    }
}